package cn.anecansaitin.firecrafting.common.integration.top;

import cn.anecansaitin.firecrafting.ModConstant;
import cn.anecansaitin.firecrafting.api.common.IResultType;
import cn.anecansaitin.firecrafting.api.common.block.entity.IFireInterfaceEntity;
import cn.anecansaitin.firecrafting.common.world.FireCraftingSavedData;
import mcjty.theoneprobe.api.*;
import mcjty.theoneprobe.apiimpl.styles.ItemStyle;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BaseFireBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;

import java.util.List;
import java.util.Objects;

public class FireCraftingProbeInfoProvider implements IProbeInfoProvider {
    private final MutableComponent INPUT = new TranslatableComponent("firecrafting.top.input").withStyle(ChatFormatting.AQUA);
    private final MutableComponent ITEM_OUT = new TranslatableComponent("firecrafting.top.item_out").withStyle(ChatFormatting.RED);
    private final MutableComponent FLUID_OUT = new TranslatableComponent("firecrafting.top.fluid_out").withStyle(ChatFormatting.BLUE);
    private final MutableComponent ENERGY_OUT = new TranslatableComponent("firecrafting.top.energy_out").withStyle(ChatFormatting.YELLOW);
    private final IItemStyle BIG = new ItemStyle().width(16).height(16);

    @Override
    public ResourceLocation getID() {
        return new ResourceLocation(ModConstant.MOD_ID);
    }

    @Override
    public void addProbeInfo(ProbeMode probeMode, IProbeInfo iProbeInfo, Player player, Level level, BlockState blockState, IProbeHitData iProbeHitData) {
        fireInfo(probeMode, iProbeInfo, player, level, blockState, iProbeHitData);
        fireInterfaceInfo(probeMode, iProbeInfo, player, level, blockState, iProbeHitData);
    }

    private void fireInfo(ProbeMode probeMode, IProbeInfo iProbeInfo, Player player, Level level, BlockState blockState, IProbeHitData iProbeHitData) {
        if (blockState.getBlock() instanceof BaseFireBlock) {
            if (level instanceof ServerLevel) {
                FireCraftingSavedData data = FireCraftingSavedData.getInstance((ServerLevel) level);
                List<ItemStack> stacks = data.getStacks(iProbeHitData.getPos());
                if (probeMode == ProbeMode.EXTENDED || probeMode == ProbeMode.DEBUG) {
                    int count = 0;
                    IProbeInfo child = null;
                    for (ItemStack stack : stacks) {
                        if (stack.isEmpty()) {
                            continue;
                        }
                        if (count > 8) {
                            count = 0;
                            child = iProbeInfo.horizontal();
                        }
                        if (child == null) {
                            child = iProbeInfo.horizontal();
                        }
                        child.item(stack, BIG);
                        count++;
                    }
                }
            }
        }
    }

    private void fireInterfaceInfo(ProbeMode probeMode, IProbeInfo iProbeInfo, Player player, Level level, BlockState blockState, IProbeHitData iProbeHitData) {
        if (level.getBlockEntity(iProbeHitData.getPos()) instanceof IFireInterfaceEntity) {
            IFireInterfaceEntity entity = Objects.requireNonNull((IFireInterfaceEntity) level.getBlockEntity(iProbeHitData.getPos()));
            IProgressStyle progressStyle = iProbeInfo.defaultProgressStyle();
            progressStyle.height(5);
            progressStyle.showText(false);
            LazyOptional<IItemHandler> input = entity.getCapForInput();
            IItemHandler itemInHandler = input.orElseThrow(RuntimeException::new);
            int count = 0;
            IProbeInfo child = null;
            //原料
            if (probeMode == ProbeMode.EXTENDED || probeMode == ProbeMode.DEBUG) {
                iProbeInfo.mcText(INPUT);
                for (int i = 0; i < itemInHandler.getSlots(); i++) {
                    ItemStack stack = itemInHandler.getStackInSlot(i);
                    if (stack.isEmpty()) {
                        continue;
                    }
                    if (count > 5) {
                        count = 0;
                        child = iProbeInfo.horizontal();
                    }
                    if (child == null) {
                        child = iProbeInfo.horizontal();
                    }
                    child.item(stack, BIG);
                    count++;
                }
            }

            //产物
            List<IResultType> types = entity.actionType();
            //流体产物
            if (types.contains(IResultType.FLUID)) {
                LazyOptional<IFluidHandler> fluidOut = entity.getCapForOutput(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY);
                if (fluidOut.isPresent()) {
                    IFluidHandler fluidHandler = fluidOut.orElseThrow(RuntimeException::new);
                    if (probeMode == ProbeMode.EXTENDED || probeMode == ProbeMode.DEBUG) {
                        iProbeInfo.mcText(FLUID_OUT);
                        child = iProbeInfo.vertical();
                        for (int i = 0; i < fluidHandler.getTanks(); i++) {
                            FluidStack fluid = fluidHandler.getFluidInTank(i);
                            child.tankSimple(fluidHandler.getTankCapacity(i), fluid);
                        }
                    }
                }
            }
            //物品产物
            if (types.contains(IResultType.ITEM)) {
                LazyOptional<IItemHandler> itemOut = entity.getCapForOutput(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY);
                if (itemOut.isPresent()) {
                    count = 0;
                    child = null;
                    IItemHandler itemOutHandler = itemOut.orElseThrow(RuntimeException::new);
                    if (probeMode == ProbeMode.EXTENDED || probeMode == ProbeMode.DEBUG) {
                        iProbeInfo.mcText(ITEM_OUT);
                        for (int i = 0; i < itemOutHandler.getSlots(); i++) {
                            ItemStack stack = itemOutHandler.getStackInSlot(i);
                            if (stack.isEmpty()) {
                                continue;
                            }
                            if (count > 5) {
                                count = 0;
                                child = iProbeInfo.horizontal();
                            }
                            if (child == null) {
                                child = iProbeInfo.horizontal();
                            }
                            child.item(stack, BIG);
                            count++;
                        }
                    }
                }
            }

            //能量产物
            if (types.contains(IResultType.ENERGY)) {
                LazyOptional<IEnergyStorage> energyOut = entity.getCapForOutput(CapabilityEnergy.ENERGY);
                if (energyOut.isPresent()) {
                    IEnergyStorage energyHandler = energyOut.orElseThrow(RuntimeException::new);
                    if (probeMode == ProbeMode.EXTENDED || probeMode == ProbeMode.DEBUG) {
                        iProbeInfo.mcText(ENERGY_OUT);
                        iProbeInfo.progress(energyHandler.getEnergyStored(), energyHandler.getMaxEnergyStored());
                    }
                }
            }
        }
    }
}
